package com.qen.repository;

import com.qen.common.GenericTypeUtils;
import org.beetl.sql.core.page.PageResult;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

/**
 * Dao超类
 *
 * @author licz
 * @data 2025年05月14日 3:12 PM
 */
public interface BaseDao<T> extends LambdaDao<T>, HandDao, JoinDao<T> {

    /**
     * 主键查询.
     *
     * @param key 主键
     * @return 数据实体类
     */
    default T findObjectByKey(Serializable key) {
        return findObjectByKey(key, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));
    }

    /**
     * 主键查询.
     *
     * @param idList 主键
     * @return 数据实体类
     */
    default List<T> findObjectByKey(List<? extends Serializable> idList) {
        return findObjectByKey(idList, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));

    }

    /**
     * sql查询.
     *
     * @param sql             sql语句
     * @param params          参数键值对,in/not in的参数 是数组
     * @param pageNum         分页页数
     * @param pageSize        分页数量
     * @param isTotalRequired 是否返回总数
     * @return 返回PageResult对象，如果isTotalRequired为true 则返回总数；getTotalRow:总数；getList:数据集合;getTotalPage 总页数；
     */
    default PageResult<T> queryEntityListPageable(String sql, Map<String, Object> params, int pageNum, int pageSize, boolean isTotalRequired) {
        return queryEntityListPageable(sql, params, pageNum, pageSize, isTotalRequired, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));
    }


    /**
     * 根据sql查询对象集合
     *
     * @param sql    sql语句
     * @param params 参数键值对,in/not in的参数 是数组
     * @return 返回指定的clz对象的集合
     */
    default List<T> queryEntityList(String sql, Map<String, Object> params) {
        return queryEntityList(sql, params, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));
    }

    /**
     * 根据sql查询对象集合
     *
     * @param sql    sql语句
     * @param params 实体对象
     * @return 返回指定的clz对象的集合
     */
    default List<T> queryEntityList(String sql, Object params) {
        return queryEntityList(sql, params, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));
    }

    /**
     * 使用Markdown格式来组织SQL文件
     *
     * @param fileName SQL查询所在的文件名
     * @param sqlMark  SQL标记
     * @param params   参数键值对,in/not in的参数 是数组
     * @return 返回指定的clz对象的集合
     */
    default List<T> queryEntityListFromMarkdown(String fileName, String sqlMark, Map<String, Object> params) {
        return queryEntityListFromMarkDown(fileName, sqlMark, params, GenericTypeUtils.getGenericType(getClass().getGenericSuperclass()));
    }

    /**
     * T 对象的 库更新，obj中需要主键，没有就不更新
     *
     * @param obj
     */
    int updateIfNotNull(Map<String, Object> obj);

    /**
     * 根据主键删除T对象.
     *
     * @param key 主键
     */
    int deleteEntityByKey(Serializable key);

    /**
     * 根据主键删除T对象.
     *
     * @param keys 主键
     */
    default int deleteEntityByKey(List<? extends Serializable> keys) {
        return deleteEntityByKey(keys, null);
    }

    /**
     * 根据主键删除T对象.
     *
     * @param keys 主键
     */
    <E> int deleteEntityByKey(List<? extends Serializable> keys, Class<E> clz);

    /**
     * 部分更新，实体类中属性为Null或不传入的则不被更新
     *
     * @param list 任意类型对象List,未考虑到数据库能接收的最大量，因此，还需要程序自己控制每批的数量，设置成每批3000个比较通用
     */
    int[] updateBatchIfNotNull(List<T> list);

    /**
     * 批量添加添加对象
     *
     * @param list
     * @param <E>
     */
    <E> int[] addBatch(List<E> list);

}
